﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Windows.Forms;
using System.Drawing;
using System.Reflection;

using J_FoundationClasses.Operacao;
using J_FoundationClasses.Programacao;
using ProcUtils;
using Montador;

namespace IDE
{
    public delegate void dlgIndicar();

    public class dgvLinhas : DataGridView
    {
        BindingSource bsLinhas;
        DataTable LIN;
        readonly string strProc;
        readonly IProcessador PROC;
        dlgIndicar Editado;

        public dgvLinhas(string prmProc, DataTable LinD, dlgIndicar prmEditado)
            : base()
        {
            DataGridViewColumn cc;

            strProc = prmProc;
            PROC = Portfolio.objProc(strProc);
            LIN = LinD;
            Editado = prmEditado;

            // configurar o GridView
            this.AllowUserToAddRows = true;
            this.AllowUserToResizeColumns = true;
            this.AllowUserToResizeRows = true;
            this.Bounds = new Rectangle(20, 20, 1200, 500);

            this.Font = new Font("Courier New", 10f);

            this.AutoGenerateColumns = false;
            bsLinhas = new BindingSource();
            bsLinhas.DataSource = LinD;
            this.DataSource = bsLinhas;

            // Criar e configurar as colunas dele.
            // A primeira coluna tem valor calculado (número da linha é sempre index+1)
            // O objeto Instrução não aparece na tela, então está no binding source mas não aqui.

            this.VirtualMode = true;  // necessario para coluna calculada

            // coluna[0]
            this.Columns.Add("NumLin", "Linha");  // virtual

            cc = new DataGridViewTextBoxColumn();  // coluna[1] "Instrucao" = representacao visual
            cc.HeaderText = "Instrução";
            cc.Name  = "RepVis";
            cc.DataPropertyName = "RepVis";
            cc.Width = 1000;
            cc.ReadOnly = true;
            this.Columns.Add(cc);


            // Capturar eventos
            this.CellEnter += new DataGridViewCellEventHandler(evhCellEnter);
            this.CellValueNeeded += new DataGridViewCellValueEventHandler(NumAutomatico);

        }

        private void NumAutomatico(object sender, DataGridViewCellValueEventArgs e)
        {
            e.Value = e.RowIndex + 1;
        }

        void evhCellEnter(object sender, DataGridViewCellEventArgs e)
        {
            // em caso nos entramos celula da instrucao, abriremos janela de editar
            object  frmPopup;  // polimórfico pq. depende do processador

            // testar onde estamos..
            if (e == null) return;
            if (e.ColumnIndex != this.Columns.IndexOf(this.Columns["RepVis"])) return;
            // agora estamos numa celula de visualizacao da instrucao. Editaremos o conteúdo.

            object objInst = (bsLinhas.Current as DataRowView).Row["Instrucao"];
            Instrucao instAtual = ((objInst != null) && (objInst != DBNull.Value)) ?
                (Instrucao)objInst :
                Portfolio.objInst(strProc);

            // abrir o formulário (depende do processador) para editar. Passar Instrução para editar
            //Type tf = FormsEditar.FormUtils.ProcToForm(PROC.GetType());
            object[] prmForm = new object[] { PROC, instAtual };
            //frmPopup = System.Activator.CreateInstance(tf, prmForm);
            frmPopup = Portfolio.objForm(strProc, prmForm);
            ((Form)frmPopup).ShowDialog();

            // disfrutar o resultado de editagem
            instAtual = (frmPopup as EditForm).InstAtual;

            (bsLinhas.Current as DataRowView).BeginEdit();
            (bsLinhas.Current as DataRowView).Row["Instrucao"] = (object)instAtual;
            (bsLinhas.Current as DataRowView).Row["RepVis"] = instAtual.RepVisual(PROC);
            bsLinhas.EndEdit();  // fixar novo valor na tabela

            Editado();
        }

    }
}
